﻿using AutoWrapper.Wrappers;
using Casbin.NET.Adapter.Dapper;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using NetCasbin;

namespace CasbinRBACDemo.MYSQL.Controllers
{
    [Route("Demo")]
    [ApiController]
    public class MYSQLDemoController : ControllerBase
    {
        private readonly Enforcer enforcer;

        /// <summary>
        /// 构造函数
        /// </summary>
        public MYSQLDemoController(Enforcer inDI)
        {
            enforcer = inDI;
        }

        /// <summary>
        /// 测试Casbin功能
        /// </summary>
        /// <returns></returns>
        [HttpGet("TestCasbin", Name = "cyl")]
        public ApiResponse TestCasbin()
        {
            //管理 API==>这些API用于获取策略中的确切对象
            //添加，删除，更新 API==>这些API允许您在运行时动态地添加、删除或编辑策略

            #region 添加策略

            Console.WriteLine("-------添加策略---------");

            enforcer.AddFunction("checkSuperAdmin", (string str) =>
            {
                return enforcer.HasRoleForUser(str, "superadmin");
            });

            var res = enforcer.HasPolicy("admin", "data", "read");

            var resAddPolicy = enforcer.AddPolicy("admin", "data", "read");
            var res1 = enforcer.AddPolicy("admin", "data2", "read");
            var res2 = enforcer.AddPolicy("roleA", "data", "read");
            enforcer.AddPolicy("roleB", "data", "read");
            enforcer.AddPolicy("roleC", "data", "read");
            enforcer.AddPolicy("roleC", "data", "read2");
            enforcer.AddPolicy("roleD", "data", "read");
            enforcer.AddPolicy("roleD", "data", "read2");
            enforcer.AddPolicy("deleteRoleD", "data", "delete");
            enforcer.AddPolicy("deleteRoleE", "deletedata", "delete");
            Console.WriteLine("添加策略" + resAddPolicy.ToString());

            #endregion 添加策略

            #region 为用户添加角色

            Console.WriteLine("-------为用户添加角色---------");
            var resAddRoleForUser = enforcer.AddRoleForUser("cyl", "admin");
            var resAddRolesForUserA = enforcer.AddRoleForUser("cylA", "roleA");
            var resAddRolesForUserB = enforcer.AddRoleForUser("cylB", "roleB");
            var resAddRolesForUserC = enforcer.AddRoleForUser("cylC", "roleC");
            var resAddRolesForUserDC = enforcer.AddRoleForUser("cylD", "roleC");
            var resAddRolesForUserDD = enforcer.AddRoleForUser("cylD", "roleD");
            var resAddRolesForUserdeletecyl = enforcer.AddRoleForUser("deletecyl", "roleD");

            #endregion 为用户添加角色

            #region 为用户添加多个角色

            Console.WriteLine("-------为用户添加多个角色---------");
            var resAddRolesForUser = enforcer.AddRolesForUser("cyl", new List<string> { "roleA", "roleB" });
            var resAddRolesForUserTwo = enforcer.AddRolesForUser("cylC", new List<string> { "roleA", "roleB" });
            //var resAddRolesForUser = enforcer.AddRolesForUser("cyl", new List<string> { "admin" }, "org1");

            #endregion 为用户添加多个角色

            #region 获取用户对应所有角色

            Console.WriteLine("-------获取用户对应所有角色---------");
            var users = enforcer.GetRolesForUser("cyl");
            foreach (var item in users)
            {
                Console.WriteLine(item);
            }
            var usersA = enforcer.GetRolesForUser("cylA");
            foreach (var item in usersA)
            {
                Console.WriteLine(item);
            }
            var usersB = enforcer.GetRolesForUser("cylB");
            foreach (var item in usersB)
            {
                Console.WriteLine(item);
            }

            #endregion 获取用户对应所有角色

            #region 获取角色对应的所有用户

            Console.WriteLine("-------获取角色对应的所有用户---------");
            var roles = enforcer.GetUsersForRole("admin");
            foreach (var item in roles)
            {
                Console.WriteLine(item);
            }
            var rolesA = enforcer.GetUsersForRole("roleA");
            foreach (var item in rolesA)
            {
                Console.WriteLine(item);
            }
            var rolesB = enforcer.GetUsersForRole("rolesB");
            foreach (var item in rolesB)
            {
                Console.WriteLine(item);
            }

            #endregion 获取角色对应的所有用户

            #region 确定用户是否具有角色

            var resHasRoleForUserCYLadmin = enforcer.HasRoleForUser("cyl", "admin");
            Console.WriteLine("检查cyl用户是否有admin角色：" + resHasRoleForUserCYLadmin.ToString());
            var resHasRoleForUserCYLroleA = enforcer.HasRoleForUser("cyl", "roleA");
            Console.WriteLine("检查cyl用户是否有roleA角色：" + resHasRoleForUserCYLroleA.ToString());

            #endregion 确定用户是否具有角色

            #region 删除用户的所有角色

            var resDeleteRoleForUser = enforcer.DeleteRoleForUser("cylC", "roleC");
            //var resDeleteRolesForUserorg1 = enforcer.DeleteRolesForUser("cylD","org1");

            #endregion 删除用户的所有角色

            #region 删除用户的所有角色

            var resDeleteRolesForUser = enforcer.DeleteRolesForUser("cylD");
            //var resDeleteRolesForUserorg1 = enforcer.DeleteRolesForUser("cylD","org1");

            #endregion 删除用户的所有角色

            #region 删除用户

            Console.WriteLine("-------删除用户---------");
            var resDeleteUser = enforcer.DeleteUser("deletecyl");

            #endregion 删除用户

            #region 删除角色

            Console.WriteLine("-------删除角色---------");
            var resDeleteRole = enforcer.DeleteRole("deleteRoleD");
            //var resDeleteRolesForUserorg1 = enforcer.DeleteRolesForUser("cylD","org1");

            #endregion 删除角色

            #region 删除权限

            Console.WriteLine("-------删除权限---------");
            //删除权限。 如果权限不存在，则返回false（也就是说不受影响）
            //var resDeletePermission = enforcer.DeletePermission("read");//这么写就有问题了
            //传入数据和数据对应的相关的权限
            var resDeletePermission = enforcer.DeletePermission("deletedata", "delete");

            #endregion 删除权限

            #region 为用户或角色添加多个权限

            var resAddPermissionForUser = enforcer.AddPermissionForUser("TestAddPermissionForUser", "read");

            #endregion 为用户或角色添加多个权限

            //var resAddPermissionsForUser = enforcer.AddPermissionsForUser("");//没有实现此方法
            var resDeletePermissionForUser = enforcer.DeletePermissionForUser("TestAddPermissionForUser", "read");
            var resDeletePermissionsForUser = enforcer.DeletePermissionsForUser("cylE");

            //获取用户具有的隐式角色。 与GetRolesForUser() 相比，该函数除了直接角色外还检索间接角色。
            var resGetPermissionsForUser = enforcer.GetPermissionsForUser("cyl");
            var resHasPermissionForUser = enforcer.HasPermissionForUser("cyl");
            var resGetImplicitRolesForUser = enforcer.GetImplicitRolesForUser("cyl");

            // 获取所有继承该角色的用户 与GetUsersForRole() 相比，这个函数检索间接用户
            //var resGetImplicitUsersForRole = enforcer.GetImplicitUsersForRole("cyl");//没有实现此方法
            var resGetImplicitPermissionsForUser = enforcer.GetImplicitPermissionsForUser("cyl");
            //获取用户拥有的所有域名
            var resGetDomainsForUser = enforcer.GetDomainsForUser("cyl");
            //返回为true的策略给用户
            //var resGetImplicitResourcesForUser = enforcer.GetImplicitResourcesForUser("cyl");//没有实现此方法

            #region 检测哪个政策允许这个请求

            //使用函数EnforceEx()。你可以像这样使用它：
            Console.WriteLine("检测哪个政策允许这个请求");
            var resEnforceEx = enforcer.EnforceEx("admin", "data", "read");
            if (resEnforceEx.Result)
            {
                foreach (var item in resEnforceEx.Explains)
                {
                    foreach (var item2 in item)
                    {
                        Console.WriteLine(item2);
                    }
                }
            }

            #endregion 检测哪个政策允许这个请求

            Console.WriteLine("-------查看有没有这条策略---------");
            Console.WriteLine(enforcer.HasPolicy("admin", "data2", "read").ToString());

            var resGetNamedPolicy = enforcer.GetNamedPolicy("p");

            Console.WriteLine("-------获取策略中的所有授权规则---------");
            var policyList = enforcer.GetPolicy();
            Console.WriteLine(policyList);
            foreach (var item in policyList)
            {
                foreach (var item2 in item)
                {
                    Console.WriteLine(item2);
                }
            }

            #region 鉴权操作

            Console.WriteLine("-------鉴权操作(admin, data, read)---------");
            var response = enforcer.Enforce("admin", "data", "read");
            Console.WriteLine(response);

            Console.WriteLine("-------鉴权操作(cyl, data1, read)---------");
            var responseTwo = enforcer.Enforce("cyl", "data1", "read");
            Console.WriteLine(responseTwo);

            enforcer.ClearPolicy();
            enforcer.LoadPolicy();

            Console.WriteLine("-------鉴权操作(cylC, data, write)---------");
            var responseAgain = enforcer.Enforce("cylC", "data", "write");
            Console.WriteLine(responseAgain);

            Console.WriteLine("-------鉴权操作(cyl, data, read)---------");
            var responsecyl = enforcer.Enforce("cyl", "data", "read");
            Console.WriteLine(responsecyl);

            #endregion 鉴权操作

            ////
            ////var PreallPolicy = enforcer.GetPolicy();
            ////var PreresLoadFilteredPolicyCYL = enforcer.Enforce("cylA", "data", "read");
            ////var LoadFilteredPolicyCYL = enforcer.LoadFilteredPolicy(new Filter
            ////{
            ////    P = new List<string> { "admin", "data", "read" },
            ////});
            ////var resGetModel = enforcer.GetModel().Model["g"]["g"].Policy;
            ////var allPolicy = enforcer.GetPolicy();

            ////var resLoadFilteredPolicyCYL = enforcer.Enforce("cylA", "data", "read");

            ////var resLoadFilteredPolicy = enforcer.LoadFilteredPolicy(new Filter
            ////{
            ////    P = new List<string> { "", "data2", "" },
            ////    G = new List<string> { "", "data2_admin" },
            ////});

            return new ApiResponse("ok");
        }
    }
}